/******************************************************************************* 
  Copyright (C), 1988-2020, zeno Tech. Co., Ltd.
  Description:  AUDIO模块内部头文件
  Function List:
            
*******************************************************************************/
              
#ifndef AUDIO_PRIV_H
#define AUDIO_PRIV_H

/*=============================================================================
                                 Includes                                  
==============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/prctl.h>


#include "log.h"
#include "cfg.h"
#include "gpio.h"
#include "sysIf.h"
#include "sysIrcut.h"
#include "sysPack.h"
#include "sysDebug.h"
#include "audioFaac.h"
#include "adc.h"
#include "list.h"

#include "AudioEnc.h"
#include "AudioIn.h"
#include "AudioDec.h"
#include "AudioOut.h"
#include "AudioAnalyse.h"

#ifdef BUILD_IAS
#include "ias.h"
#endif

#include "rkmedia_aenc.h"
#include "rkmedia_api.h"
#include "StreamComposeMgr.h"
#include "speex_resampler.h"
/*=============================================================================
                               Macro Definition
==============================================================================*/
/* 最大输入输出音频通道数 */
#define AUDIO_LOGICIN_MAX       8
#define AUDIO_LOGICOUT_MAX      8

/* 最大编解码音频通道数 */
#define AENC_SUPPORT_CHN 	     16
#define ADEC_SUPPORT_CHN         16
//#define AENC_PER_FRM_NUM         512
//#define AENC_FRAME_LEN           (AENC_PER_FRM_NUM * 2)
//#define AENC_LINEIN_PER_FRM_NUM  512 
//#define AENC_LINEIN_FRAME_LEN    (AENC_LINEIN_PER_FRM_NUM * 2)
#define AENC_MIC_NUM_MAX (32)
#define AENC_DATA_MAX_SIZE 		(AENC_MIC_NUM_MAX * 1024)
//#define AI_SAMPLE_RATE  (32000)
//#define AO_SAMPLE_RATE  (32000)
//#define AUDIO_AI_MIC_CH (8)
#define AUDIO_AI_CH (0)
#define AUDIO_AO_CH (0)

#define AUDIO_LINEIN_CH (2)
#define AUDIO_AI_LINEIN_CH (1)
#define AUDIO_AO_LINEOUT_CH (1)

#define AUDIO_UAC_CH (2)
#define AUDIO_AI_UAC_CH (2)
#define AUDIO_AO_UAC_CH (2)

#define OPEN_SOURCE_AAC

#ifdef AUDIO_HI3559AV100
#define AI_DEV_ID   1
#define AO_DEV_ID	1
#else
#define AI_DEV_ID0   0
#define AI_DEV_ID1   1
#define AO_DEV_ID	 0

#define AI_DEV_ID   1
#endif
#define AENC_STREAM_PER_CHN  1  // 1 Main stream
#define ADEC_STREAM_PER_CHN  1
#define	INPUT_MIN_DEC_DATA	(0x64)



#define MAX_AI_DEV  2

/* 海思音频帧头长度 */
#define HI_AUDIO_HEAD  4    

#define PCM_FRAME_LEN   1536   

/* 不知道为什么3559a上去掉了这个枚举值,先保证编译通过,后续调试aac再确定 */
#if defined(AUDIO_HI3559AV100)||defined(AUDIO_HI3516CV500)||defined(AUDIO_HI3516EV200)||defined(AUDIO_HI3519AV100)
#define PT_AACLC 42
#endif

#define gettid() syscall(__NR_gettid)

#define MAX_CHN_NUM_AMIX 16

#define AUDIO_RESAMPLER_BASE 48000 //16000

#define AUDIO_16BIT_LEN   2

#define AUDIO_ALGO_44100_TIME 10

#define AUDIO_RESAMPLE_44100HZ 44100

#define AUDIO_RESAMPLER_TIME_44100_BASE (AUDIO_RESAMPLER_BASE * AUDIO_ALGO_44100_TIME / 1000)

#define AUDIO_RESAMPLE_OUT_TO_LIST_LEN (AUDIO_RESAMPLER_BASE * AUDIO_ALGO_TIME * AUDIO_16BIT_LEN / 1000)

#define AUDIO_RESAMPLE_10MS_44100HZ (AUDIO_RESAMPLE_44100HZ * AUDIO_ALGO_44100_TIME / 1000)

#define AUDIO_RESAMPLE_10MS_16BIT_44100HZ (AUDIO_RESAMPLE_44100HZ * AUDIO_ALGO_44100_TIME * AUDIO_16BIT_LEN / 1000)

#define AUDIO_ALGO_TIME 16

#define MAX_PCM_SIZE 8*1024

/* 解码empty_buf 最大长度 */
#define ADEC_ACOMMLIST_LENGTH (16)


/*=============================================================================
                        Local Structures and Typedef 
==============================================================================*/

/* 录音控制结构体 */
typedef struct
{
	int recordFd; 		     /* 录音文件描述符 */
    unsigned int streamId;   /* 码流类型 */
    unsigned int frameNum;   /* 录音的帧数 */
    unsigned int isPackData; /* 是否封装 */
    char recordPath[32];     /* 存储录音的路径 */
    char recordName[32];     /* 录音名 */
}AUDIO_recordData_t;

/* 音频编码帧率统计控制结构体 */
typedef struct
{
    unsigned int streamId;   /* 码流类型 */
    unsigned int isStatFps;  /* 是否统计音频帧率 */
    unsigned int oldTime;
    unsigned int frameCount; /* 帧率统计 */
}AUDIO_encFps_t;


enum
{
    AI_STREAM_STOP = 0,             /* 停止音频码流 */
    AI_STREAM_START,                /* 启动音频码流 */
}; 

typedef struct
{
    struct list_head list;
    uint64 pts;
    char *pBuf;
    int len;
    void* revered;
} ACOMM_listInfo_t;


typedef struct
{
    unsigned int refCount;      /* ai 接口引用计数 */
    AudioInput audioInput;      /* ai 接口结构体 */
    AI_CHN_ATTR_S aiChnAttr;    /* ai 输入通道属性 */
    int aiChn;                  /*ai通道编号*/
    int aiChnState;             /*ai通道状态*/
    AudioSource aiSource;       /*ai输入源*/
    unsigned char isNeedResampler; /*ai输入是否重采样*/

    SpeexResamplerState *resampler; /*音频重采样控制指针*/
    int nbSamples; /*音频输出样本数*/  
    int resamplerLen; /*音频重采样单次的数据量*/

    uint8 discardFlg; /*初始化丢帧标记*/

    struct list_head emptyBuf;         	/* 空闲跟踪队列 */
	struct list_head fullBuf;           /* 跟踪队列 */
	pthread_mutex_t aiBufLock;          /* 队列锁 */
	ACOMM_listInfo_t listBuf[16];  	    /* 跟踪结果信息 */
	int maxBufLen;

	uint64 lastPts;	/* 上一帧输入数据的时间戳*/ 	
}AI_ctl_t;


typedef enum
{
    AENC_STREAM_STOP,                 /* 停止音频码流 */
    AENC_STREAM_START,                /* 启动音频码流 */
} ENC_streamState_t;

typedef enum
{
    ADEC_STATUS_STOP = 0,
    ADEC_STATUS_START = 1,
}SPK_OUT_STA_t;

typedef struct
{
    unsigned int refCount;      /* 接口引用计数 */
    unsigned int streamId;      /* 接口编号 */
    AudioEncStream aencStream;  /* 码流类型号 */
    AudioEncoder audioEncoder;  /* 接口结构体 */
    unsigned int aencState;     /* 码流状态 */
    int aencChn;                /* aenc通道编号 */
    AudioEncFormat aencFormat;  /* aenc音频编码 */      
    //int8 *pAencBuf;           /* 音频编码数据指针 */ 
    AUDIO_recordData_t recordData;  /* 调试录音控制结构体 */
    int aencFps;
    
    AAC_ctl_t *pAacCtl; /* AAC编码控制指针 */

    struct list_head emptyBuf;         	/* 空闲跟踪队列 */
	struct list_head fullBuf;           /* 跟踪队列 */
	pthread_mutex_t aencBufLock;        /* 队列锁 */
	ACOMM_listInfo_t listBuf[5];  	    /* 跟踪结果信息 */
	int maxBufLen;

    ACOMM_listInfo_t pListPacket;
}AENC_ctl_t;


enum
{
    ADEC_STOP = 0,             /* 停止音频码流 */
    ADEC_START,                /* 启动音频码流 */
};

typedef struct
{
    unsigned int refCount;      /* 接口引用计数 */
    unsigned int streamId;      /* 接口编号 */
    AudioDecoder audioDecoder;  /* 接口结构体 */
    unsigned int adecState;     /* 码流状态 */
    unsigned int oldAdecState;  /* 之前的码流状态 */
    AudioEncPackType packType;  /* 数据封装类型 */
    int adecChn;                /* adec通道编号 */  
    AudioEncType adecType;      /* 音频解码的类型 */
    AudioDecFormat adecFormat;  /* 音频解码参数 */    
    int adecMode;               /* 音频解码模式，G726下是压缩率 */
    AUDIO_recordData_t recordData;  /* 调试录音控制结构体 */

    AAD_ctl_t *pAadCtl;         /*AAC解码控制指针*/

    SpeexResamplerState *resampler; /*音频重采样控制指针*/
    int nbSamples; /*音频输出样本数*/  
    int resamplerLen; /*音频重采样单次的数据量*/

    struct list_head emptyBuf;         	/* 空闲跟踪队列 */
	struct list_head fullBuf;           /* 跟踪队列 */
	pthread_mutex_t adecBufLock;          /* 队列锁 */
	ACOMM_listInfo_t listBuf[ADEC_ACOMMLIST_LENGTH];  	    /* 跟踪结果信息 */
	int maxBufLen;
}ADEC_ctl_t;


enum
{
    AO_STREAM_STOP = 0,             /* 停止音频码流 */
    AO_STREAM_START,                /* 启动音频码流 */
};
typedef struct
{
    unsigned int refCount;              /* ao 接口引用计数 */
    AudioOutput audioOutput;            /* ao 接口结构体 */
    int aoChn;                          /* ao 输出通道 */
    int aoChnState;                     /* ao通道状态 */
    AO_CHN_ATTR_S aoChnAttr;            /* ao通道属性 */
}AO_ctl_t;


typedef struct
{
    uint64 storePts; /* 流的时间戳 */
    StreamInType streamType; /* 流的类型 */
    ACOMM_listInfo_t listStreamFrame; /* 流的基本信息 */
    uint8   multiplexNums;  /*当前路流输出复用次数*/

    pthread_rwlock_t  rwLock;     /* buf读写锁 */
   
} AMIX_composeInfo_t;

/* 流拼接控制结构体 */
typedef struct
{
    AMIX_composeInfo_t decComposeBuf[MAX_CHN_NUM_AMIX]; /* 保存最新输入音频数据的buf */   
    
    uint64  newPts[MAX_CHN_NUM_AMIX];    /*最新流的时间戳*/
    uint8   decComposeLen[MAX_CHN_NUM_AMIX];  /*当前路流输出已使用次数*/
    uint8   userNums[MAX_CHN_NUM_AMIX];  /*当前路流输出已使用次数*/

    pthread_mutex_t  mutex_len[MAX_CHN_NUM_AMIX]; 		   /* len读写锁 */

    pthread_mutex_t mutex_run[MAX_CHN_NUM_AMIX];
    pthread_cond_t cond_run[MAX_CHN_NUM_AMIX];
    int running[MAX_CHN_NUM_AMIX];
}AMIX_composeCtl_t;


typedef struct
{
    int audioInChn;            /*音频输入通道的个数,由配置文件获取*/   
    int audioInTrack;          /*音频输入声道，左右立体声,由配置文件获取*/
    int audioInMode;           /*音频输入模式,0:linein, 1:micin由配置文件获取*/
    int lineinGpio;            /*linein输入的gpio index*/
    int lineinLevel;           /*linein输入的有效电平值*/
    int lineinAdcChn;          /*linein输入的adc通道*/
    int lineinAdcLevel;        /*linein输入经adc转换计算的有效电平值*/
    void * lineinHadc;         /*adc资源句柄*/
    int lineoutGpio;           /*lineout输出的gpio index*/
    int lineoutLevel;          /*lineout输出的有效电平值*/
    int lineoutType;           /*lineout输出的类型*/
    unsigned int gpioLevel;    /*linein输入的电平值*/
    unsigned int supportAac;   /* 是否支持AAC编解码 */
    unsigned int supportAec;   /* 是否支持回声消除算法 */
#if defined(AUDIO_HI3519)||defined(AUDIO_HI3519V101)||defined(AUDIO_HI3516CV300)||defined(AUDIO_HI3559AV100)||defined(AUDIO_HI3516CV500)||defined(AUDIO_HI3516EV200)||defined(AUDIO_HI3519AV100)
    AI_TALKVQE_CONFIG_S aiVqeAttr; /*音频输入声音质量增强配置结构体*/
#else
    //AI_VQE_CONFIG_S aiVqeAttr; /*音频输入声音质量增强配置结构体*/
#endif
#ifdef HIMPP_V2_0
    AO_VQE_CONFIG_S aoVqeAttr; /*音频输出声音质量增强配置结构体*/
#endif
#ifndef HIMPP_V2_0
    //AI_HPF_ATTR_S aiHpfAttr;   /*设置AI的声音高通滤波功能相关属性*/
#endif
    //AIO_ATTR_S aiAttr[MAX_AI_DEV];         /*音频输入设备属性结构体*/
    //AUDIO_DEV aiDevId[MAX_AI_DEV];	       /*音频设备号*/
    AI_CHN aiChn;              /*ai通道编号*/

    /* 音频输入接口检测线程 */
    pthread_t audioInThd;

    int audioOutChn;           /*音频输出通道的个数,由配置文件获取*/
    int audioOutTrack;          /*音频输入声道，左右立体声,由配置文件获取*/
    //AIO_ATTR_S aoAttr;         /*音频输出设备属性结构体*/
    //AUDIO_DEV aoDevId;	       /*音频设备号*/
    AO_CHN aoChn;              /*ao通道编号*/
}AIO_ctl_t;

#ifdef BUILD_IAS
/* ias算法状态 */
typedef enum
{
    IAS_ALG_START,
    IAS_ALG_STOP
}IAS_algState_t;

/* 视频分析控制结构体 */
typedef struct
{
    unsigned int refCount;              /* analyser 接口引用计数 */
    AudioAnalyser audioAnalyser;        /* analyser 接口结构体 */
    IAS_algState_t iasAlgState;			/* 音频分析状态 */
    void *hIas;                         /* IAS算法句柄 */
    int	channel;					    /* 视频分析通道号 */
    unsigned int analyseSeq;            /* 帧序号 */
    IAS_result_t iasResult;			    /* 音频分析结果 */
    unsigned int serviceTypeMask;		/* 支持的场景掩码,见AudioAnalyseSceneType */	
} ANALYSER_ctl_t;
#endif

/* AUDIO模块控制结构体 */
typedef struct
{
    /* 通道控制结构体指针数组 */
    AENC_ctl_t *pEncCtls[AENC_SUPPORT_CHN];

    /* 保证音频编码通道操作线性 */
    pthread_mutex_t audioMutex;

    /* 保证ai接口线性调用 */
    pthread_mutex_t aiMutex;

    /* 保证ao接口线性调用 */
    pthread_mutex_t aoMutex;

    /* ai绑定aenc线程 */
    pthread_t aiToAencThd;

    /* 保证ai绑定aenc线性调用 */
    pthread_mutex_t aiAencMutex;

    /* 保证音频解码通道操作线性 */
    pthread_mutex_t adecMutex;

    int bAinStart;

    /* Ai结构体 */
    AI_ctl_t *pAiCtls[AUDIO_LOGICIN_MAX];

    /* ADEC结构体指针数组 */
    ADEC_ctl_t *pAdecCtls[ADEC_SUPPORT_CHN];

    /* AO结构体 */
    AO_ctl_t *pAoCtls[AUDIO_LOGICOUT_MAX];

    /* audio codec是否恢复默认设置,只在设备启动的时候恢复 */
    int isAcodecReset;

    /* 是否支持语音增强功能，与音频采样率有关 */
    int isSetVqe;

    /* 是否创建音频通道 */
    int bCreatAudio;

    /* AIO结构体 */
    AIO_ctl_t aioCtl;

#ifdef BUILD_IAS
    /* 音频分析控制结构体 */
    ANALYSER_ctl_t *pAnalyserCtl;

    /* 保证音频分析接口线性调用 */
    pthread_mutex_t analyserMutex;
#endif
	
    int logicChnInNum;			/* 逻辑输入通道数 */
    int logicChnInMask[AUDIO_LOGICIN_MAX]; /* 逻辑输入通道声道属性 */
    int logicChnOutNum;			/* 逻辑输出通道数 */
    int logicChnOutMask[AUDIO_LOGICOUT_MAX]; /* 逻辑输入通道声道属性 */

    AAC_audioCfg_t pAacCfg;
    AAC_ctl_t *pAacCtl;
    AI_CHN_ATTR_S ai_attr[AENC_SUPPORT_CHN * AENC_STREAM_PER_CHN];

 
    /* 音频混音控制结构体指针数组 */
    AMIX_composeCtl_t* pComposeCtl;
    /* 保证通道操作线性 */
    pthread_mutex_t composeMutex;

    /* 条件变量线程调度唤醒 */
    int sharedData_ai[MAX_CHN_NUM_AMIX];
    pthread_mutex_t mutex_ai[MAX_CHN_NUM_AMIX];
    pthread_cond_t cond_ai;

}AUDIO_ctl_t;

/*=============================================================================
                             extern  Variables                                  
==============================================================================*/
extern AUDIO_ctl_t audioCtl_g;

/*=============================================================================
                             Function Definition                                  
==============================================================================*/ 

/*******************************************************************************
  Function:     AUDIO_ResetAcodec
  Description:  将Audio Codec恢复为默认设置
  Input:        无
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_ResetAcodec(void);

#if 0
/*******************************************************************************
  Function:     AUDIO_CfgAcodec
  Description:  设置Audio Codec配置
  Input:        - enSample: 音频采样率
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_CfgAcodec(AUDIO_SAMPLE_RATE_E enSample);
#endif

/*******************************************************************************
  Function:     AUDIO_SetAiLineMic
  Description:  设置音频输入为mic模式
  Input:        - mode:音频输入模式,0:linein, 1:micin
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_SetAiLineMic(int mode);

/*******************************************************************************
  Function:     AUDIO_SetAiVol
  Description:  设置音频输入的音量
  Input:        - volume: 音频音量
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_SetAiVol(unsigned int volume);

#if 0
/*******************************************************************************
  Function:     AUDIO_SetAoVol
  Description:  设置音频输出的音量
  Input:        - AoDevId: 设备号
                - volume: 音频输出音量
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_SetAoVol(AUDIO_DEV AoDevId, unsigned int volume);
#endif

/*******************************************************************************
  Function:     AUDIO_AoDownPower
  Description:  音频输出的下电控制
  Input:        - enable: 是否关闭AO的电源
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_AoDownPower(unsigned int enable);

/*******************************************************************************
  Function:     AUDIO_AiDownPower
  Description:  音频输入的下电控制
  Input:        - enable: 是否关闭AI的电源
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_AiDownPower(unsigned int enable);

/*******************************************************************************
  Function:     AI_Creat
  Description:  创建音频输入输出通道
  Input:        - pAioCtl: 音频编码通道控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_Creat(AIO_ctl_t *pAioCtl);

/*******************************************************************************
  Function:     AI_Destory
  Description:  注销音频输入输出通道
  Input:        - pAioCtl: 音频编码通道控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_Destory(AIO_ctl_t *pAioCtl);

/*******************************************************************************
  Function:     AUDIO_SetFormat
  Description:  设置音频通道属性
  Input:        - frequency: 采样率
                - depth: 采样宽度
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_SetFormat(int frequency, int depth);

/*******************************************************************************
  Function:     AI_CreatTrdAiAenc
  Description:  创建音频输入绑定音频编码线程
  Input:        - pAudioCtl: 音频控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_CreatTrdAiAenc(AUDIO_ctl_t *pAudioCtl);

/*******************************************************************************
  Function:     AI_DestoryTrdAiAenc
  Description:  销毁音频输入绑定音频编码线程
  Input:        - pAudioCtl: 音频控制结构体指针
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int AUDIO_DestoryTrdAiAenc(AUDIO_ctl_t *pAudioCtl);

#ifdef BUILD_IAS
/*******************************************************************************
  Function:     ANALYSER_GetIasResult
  Description:  获取音频分析结果
  Input:        - pAnalyserCtl: 音频检测结构体
                - pData: 音频数据指针
                - dataLen: 音频数据长度
  Output:       无
  Return:       0: 操作成功
                -1: 操作失败
  Others:       无
*******************************************************************************/
int ANALYSER_GetIasResult(ANALYSER_ctl_t *pAnalyserCtl, char *pData, int dataLen);
#endif

#endif  /*AUDIO_PRIV_H*/

